library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
method from
print.tbl_lazy
print.tbl_sql
── Attaching packages ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.1 ──
✔ ggplot2 3.3.6 ✔ purrr 0.3.4
✔ tibble 3.1.7 ✔ dplyr 1.0.9
✔ tidyr 1.2.0 ✔ stringr 1.4.0
✔ readr 2.1.2 ✔ forcats 0.5.1
── Conflicts ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
library(janitor)
Attaching package: ‘janitor’
The following objects are masked from ‘package:stats’:
chisq.test, fisher.test
library(skimr)
Registered S3 methods overwritten by 'htmltools':
method from
print.html tools:rstudio
print.shiny.tag tools:rstudio
print.shiny.tag.list tools:rstudio
library(tsibble)
Attaching package: ‘tsibble’
The following objects are masked from ‘package:base’:
intersect, setdiff, union
library(lubridate)
Attaching package: ‘lubridate’
The following object is masked from ‘package:tsibble’:
interval
The following objects are masked from ‘package:base’:
date, intersect, setdiff, union
beds <- read_csv("raw_data/non_covid_raw_data/beds_by_nhs_board_of_treatment_and_specialty.csv") %>%
clean_names()
Warning: One or more parsing issues, see `problems()` for details
Rows: 30458 Columns: 20
── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (10): Quarter, QuarterQF, HB, HBQF, Location, LocationQF, Specialty, SpecialtyQF, SpecialtyName, SpecialtyNameQF
dbl (5): AllStaffedBeddays, TotalOccupiedBeddays, AverageAvailableStaffedBeds, AverageOccupiedBeds, PercentageOccupancy
lgl (5): AllStaffedBeddaysQF, TotalOccupiedBeddaysQF, AverageAvailableStaffedBedsQF, AverageOccupiedBedsQF, PercentageOccupancyQF
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
glimpse(beds)
skim(beds)
view(beds)
beds %>%
arrange(desc(all_staffed_beddays))
beds %>%
distinct(location)
beds %>%
distinct(hb)
beds %>%
distinct(all_staffed_beddays)
beds %>%
distinct(total_occupied_beddays)
beds %>%
ggplot(aes(x = total_occupied_beddays)) +
geom_histogram(col = "white")+
scale_x_log10()
beds %>%
ggplot(aes(x = average_occupied_beds)) +
geom_histogram(col = "white")+
scale_x_log10()
beds %>%
ggplot(aes(x = percentage_occupancy)) +
geom_histogram(col = "white")
beds_select <- beds %>%
mutate(date = yq(quarter),
year = year(date),
month = month(date, label = TRUE, abbr = FALSE),
season = case_when(
str_detect(month, "January") ~ "Winter",
str_detect(month, "April") ~ "Spring",
str_detect(month, "July") ~ "Summer",
str_detect(month, "October") ~ "Autumn"),
season = factor(season, order = TRUE)) %>%
select(quarter, hb, location, specialty_name, all_staffed_beddays, total_occupied_beddays, average_available_staffed_beds, average_occupied_beds, percentage_occupancy, date, year, month, season)
beds_select %>%
filter(hb == "S92000003")
beds_select %>%
filter(!is.na(percentage_occupancy),
specialty_name == "All Acute") %>%
group_by(quarter) %>%
summarise(mean_percentage_occupancy = mean(percentage_occupancy)) %>%
ggplot(aes(x = quarter,
y = mean_percentage_occupancy)) +
geom_point() +
geom_line(group = 1)

beds_select %>%
filter(!is.na(percentage_occupancy)) %>%
group_by(quarter) %>%
summarise(mean_percentage_occupancy = mean(percentage_occupancy)) %>%
ggplot(aes(x = quarter,
y = mean_percentage_occupancy)) +
geom_col()
beds_select %>%
filter(!is.na(total_occupied_beddays)) %>%
group_by(quarter) %>%
summarise(mean_occupied_beddays = mean(total_occupied_beddays)) %>%
ggplot(aes(x = quarter,
y = mean_occupied_beddays)) +
geom_point() +
geom_line(group = 1)
beds_select %>%
filter(!is.na(all_staffed_beddays)) %>%
group_by(quarter) %>%
summarise(mean_staffed_beddays = mean(all_staffed_beddays)) %>%
ggplot(aes(x = quarter,
y = mean_staffed_beddays)) +
geom_point() +
geom_line(group = 1)
beds_select %>%
filter(!is.na(average_available_staffed_beds)) %>%
group_by(quarter) %>%
summarise(mean_avg_staffed_beddays = mean(average_available_staffed_beds)) %>%
ggplot(aes(x = quarter,
y = mean_avg_staffed_beddays)) +
geom_point() +
geom_line(group = 1)
beds_select %>%
filter(!is.na(average_available_staffed_beds)) %>%
mutate(empty_beddays = all_staffed_beddays - total_occupied_beddays) %>%
group_by(quarter) %>%
summarise(mean_empty = mean(empty_beddays)) %>%
ggplot(aes(x = quarter,
y= mean_empty)) +
geom_point() +
geom_line(group = 1)
beds_select %>%
filter(!is.na(percentage_occupancy)) %>%
group_by(quarter, hb) %>%
summarise(mean_percentage_occupancy = mean(percentage_occupancy)) %>%
ggplot(aes(x = quarter,
y = mean_percentage_occupancy)) +
geom_point() +
geom_line(aes(group = hb, colour = hb))
beds_select %>%
filter(!is.na(percentage_occupancy)) %>%
group_by(quarter, specialty_name, hb) %>%
summarise(mean_percentage_occupancy = mean(percentage_occupancy)) %>%
filter(mean_percentage_occupancy > 50) %>%
ggplot(aes(x = quarter,
y = mean_percentage_occupancy)) +
geom_point() +
geom_line(aes(group = specialty_name, colour = specialty_name)) +
theme(legend.position = "none") +
facet_wrap(~ hb)
beds_select %>%
distinct(specialty_name)
beds_select %>%
filter(specialty_name %in% c("All Acute", "Accident & Emergency", "Intensive Care Medicine")) %>%
group_by(quarter, specialty_name) %>%
summarise(mean_pct = mean(percentage_occupancy)) %>%
ggplot(aes(x = quarter,
y = mean_pct)) +
geom_point() +
geom_line(aes(group = specialty_name, colour = specialty_name))
beds_select %>%
filter(location == "S08000019",
quarter == "2017Q1")
beds_select %>%
filter(!is.na(percentage_occupancy),
percentage_occupancy == 100) %>%
group_by(quarter, hb) %>%
summarise(mean_avg_occupied_beds = mean(average_occupied_beds)) %>%
ggplot(aes(x = quarter,
y = mean_avg_occupied_beds)) +
geom_point() +
geom_line(aes(group = hb, colour = hb))
`
beds_select %>%
filter(!is.na(average_occupied_beds)) %>%
group_by(quarter) %>%
summarise(mean_average_occupied_beds = mean(average_occupied_beds)) %>%
ggplot(aes(x = quarter,
y = mean_average_occupied_beds)) +
geom_point() +
geom_line(group = 1)
beds_select %>%
group_by(year) %>%
summarise(mean_year_bed = mean(average_occupied_beds)) %>%
ggplot(aes(x = year,
y = mean_year_bed)) +
geom_line()
beds_select %>%
group_by(season) %>%
summarise(mean_year_bed = mean(average_occupied_beds)) %>%
ggplot(aes(x = season,
y = mean_year_bed)) +
geom_col() +
scale_x_discrete(limits = c("Spring", "Summer", "Autumn", "Winter"))
beds_select %>%
filter(!is.na(percentage_occupancy)) %>%
group_by(season) %>%
summarise(mean_prct_beds = mean(percentage_occupancy)) %>%
ggplot(aes(x = season,
y = mean_prct_beds)) +
geom_col() +
scale_x_discrete(limits = c("Spring", "Summer", "Autumn", "Winter"))
beds_select %>%
filter(!is.na(total_occupied_beddays)) %>%
group_by(season) %>%
summarise(mean_occupied_beddays = mean(total_occupied_beddays)) %>%
ggplot(aes(x = season,
y = mean_occupied_beddays)) +
geom_col() +
scale_x_discrete(limits = c("Spring", "Summer", "Autumn", "Winter"))
beds_select %>%
filter(quarter == "2016Q4")
beds_select %>%
ggplot(aes(x = season,
y = percentage_occupancy)) +
geom_col() +
facet_wrap(~ specialty_name)
beds_select %>%
filter(!is.na(percentage_occupancy)) %>%
group_by(specialty_name, month) %>%
summarise(mean_pct_speciality = mean(percentage_occupancy)) %>%
ggplot(aes(x = month,
y = mean_pct_speciality)) +
geom_point() +
geom_line(aes(group = specialty_name, colour = specialty_name))+
theme(legend.position = "none")
beds_select %>%
filter(percentage_occupancy == 100,
year == 2017) %>%
group_by(season, hb) %>%
summarise(count = n()) %>%
ggplot(aes(x = season,
y = count)) +
geom_col(aes(fill = hb), position = "dodge")
beds_select %>%
mutate(bins =
case_when(percentage_occupancy < 25 ~ "<25",
percentage_occupancy < 50 ~ "25-50",
percentage_occupancy < 75 ~ "50-75",
percentage_occupancy > 75 ~ ">75"
)
) %>%
filter(bins == "<25") %>%
group_by(season) %>%
summarise(count = n())
beds_select %>%
filter(specialty_name == "Accident & Emergency") %>%
group_by(quarter) %>%
summarise(mean_pct = mean(percentage_occupancy)) %>%
ggplot(aes(x = quarter,
y = mean_pct)) +
geom_point() +
geom_line(group = 1)
simd_treatment <- read_csv("raw_data/non_covid_raw_data/inpatient_and_daycase_by_nhs_board_of_treatment_and_simd.csv") %>% clean_names()
Rows: 40821 Columns: 18
── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (11): Quarter, QuarterQF, HB, HBQF, Location, LocationQF, AdmissionType, AdmissionTypeQF, SIMDQF, AverageLengthOfEpisodeQF, AverageLengthOfStayQF
dbl (7): SIMD, Episodes, LengthOfEpisode, AverageLengthOfEpisode, Stays, LengthOfStay, AverageLengthOfStay
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
simd_treatment %>%
filter(hb == "S92000003")
simd_treatment %>%
filter(!is.na(average_length_of_stay)) %>%
group_by(quarter) %>%
summarise(mean_avg_stay = mean(average_length_of_stay)) %>%
ggplot(aes(x = quarter,
y = mean_avg_stay)) +
geom_point() +
geom_line(group = 1)

simd_treatment %>%
filter(!is.na(average_length_of_stay)) %>%
group_by(quarter, admission_type) %>%
summarise(mean_avg_stay = mean(average_length_of_stay)) %>%
ggplot(aes(x = quarter,
y = mean_avg_stay)) +
geom_point() +
geom_line(aes(group = admission_type, colour = admission_type))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

simd_treatment %>%
filter(!is.na(average_length_of_stay)) %>%
group_by(quarter, simd) %>%
summarise(mean_avg_stay = mean(average_length_of_stay)) %>%
ggplot(aes(x = quarter,
y = mean_avg_stay)) +
geom_point() +
geom_line(aes(group = simd, colour = simd))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

simd_treatment %>%
filter(!is.na(average_length_of_stay),
simd == 5) %>%
group_by(quarter, simd) %>%
summarise(mean_avg_stay = mean(average_length_of_stay)) %>%
ggplot(aes(x = quarter,
y = mean_avg_stay)) +
geom_point() +
geom_line(aes(group = simd, colour = simd))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

simd_treatment %>%
filter(!is.na(average_length_of_stay),
simd == 1) %>%
mutate(simd = replace_na(simd, 0)) %>%
group_by(quarter, simd) %>%
summarise(mean_avg_stay = mean(average_length_of_stay)) %>%
ggplot(aes(x = quarter,
y = mean_avg_stay)) +
geom_point() +
geom_line(aes(group = simd, colour = simd))
Error in `mutate()`:
! Problem while computing `simd = replace_na(simd, 0)`.
Caused by error in `vec_assign()`:
! Can't convert `replace` <double> to match type of `data` <factor<cd34a>>.
Backtrace:
1. ... %>% ggplot(aes(x = quarter, y = mean_avg_stay))
11. tidyr:::replace_na.default(simd, 0)
12. vctrs::vec_assign(data, missing, replace, x_arg = "data", value_arg = "replace")
simd_treatment %>%
filter(!is.na(average_length_of_stay)) %>%
group_by(quarter, simd) %>%
summarise(mean_avg_stay = mean(average_length_of_stay)) %>%
ggplot(aes(x = quarter,
y = mean_avg_stay)) +
geom_point() +
geom_line(aes(group = simd, colour = simd))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

simd_treatment %>%
filter(!is.na(average_length_of_episode)) %>%
group_by(quarter) %>%
summarise(mean_avg_episode = mean(average_length_of_episode)) %>%
ggplot(aes(x = quarter,
y = mean_avg_episode)) +
geom_point() +
geom_line(group = 1)

simd_treatment %>%
filter(!is.na(average_length_of_episode)) %>%
group_by(quarter, admission_type) %>%
summarise(mean_avg_epidsode = mean(average_length_of_episode)) %>%
ggplot(aes(x = quarter,
y = mean_avg_epidsode)) +
geom_point() +
geom_line(aes(group = admission_type, colour = admission_type))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

simd_treatment %>%
filter(!is.na(average_length_of_episode)) %>%
group_by(quarter, simd) %>%
summarise(mean_avg_epidsode = mean(average_length_of_episode)) %>%
ggplot(aes(x = quarter,
y = mean_avg_epidsode)) +
geom_point() +
geom_line(aes(group = simd, colour = simd))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

simd_treatment %>%
filter(!is.na(average_length_of_episode),
simd == 5) %>%
group_by(quarter) %>%
summarise(mean_avg_episode = mean(average_length_of_episode)) %>%
ggplot(aes(x = quarter,
y = mean_avg_episode)) +
geom_point() +
geom_line(group = 1)

simd_treatment %>%
filter(!is.na(average_length_of_episode),
simd == 1) %>%
group_by(quarter) %>%
summarise(mean_avg_episode = mean(average_length_of_episode)) %>%
ggplot(aes(x = quarter,
y = mean_avg_episode)) +
geom_point() +
geom_line(group = 1)
simd_treatment %>%
filter(!is.na(episodes)) %>%
group_by(quarter, simd) %>%
summarise(mean_epidsode = mean(episodes)) %>%
ggplot(aes(x = quarter,
y = mean_epidsode)) +
geom_point() +
geom_line(aes(group = simd, colour = simd))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

simd_treatment %>%
filter(is.na(simd))
simd_treatment %>%
filter(!is.na(stays)) %>%
group_by(quarter, simd) %>%
summarise(total_stays = sum(stays)) %>%
ggplot(aes(x = quarter,
y = total_stays)) +
geom_point() +
geom_line(aes(group = simd, colour = simd))
age_and_sex <- read_csv("raw_data/non_covid_raw_data/inpatient_and_daycase_by_nhs_board_of_treatment_age_and_sex.csv") %>% clean_names()
Rows: 129393 Columns: 18
── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (12): Quarter, QuarterQF, HB, HBQF, Location, LocationQF, AdmissionType, AdmissionTypeQF, Sex, Age, AverageLengthOfEpisodeQF, AverageLengthOfStayQF
dbl (6): Episodes, LengthOfEpisode, AverageLengthOfEpisode, Stays, LengthOfStay, AverageLengthOfStay
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
age_and_sex %>%
filter(sex == "Female",
age == "0-9 years")
age_and_sex %>%
filter(!is.na(average_length_of_stay)) %>%
group_by(quarter) %>%
summarise(avg_length_of_stay = mean(average_length_of_stay)) %>%
ggplot(aes(x = quarter,
y = avg_length_of_stay)) +
geom_point() +
geom_line(group = 1)

age_and_sex %>%
group_by(quarter, age) %>%
summarise(length_of_stay = mean(length_of_stay)) %>%
ggplot(aes(x = quarter,
y = length_of_stay)) +
geom_point() +
geom_line(aes(group = age,
colour = age))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

age_and_sex %>%
filter(!is.na(average_length_of_stay)) %>%
group_by(quarter, age) %>%
summarise(avg_length_of_stay = mean(average_length_of_stay)) %>%
ggplot(aes(x = quarter,
y = avg_length_of_stay)) +
geom_point() +
geom_line(aes(group = age,
colour = age))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

age_and_sex %>%
filter(!is.na(average_length_of_episode),
age == "10-19 years",
sex == "Female") %>%
group_by(quarter, age) %>%
summarise(avg_length_of_episode = mean(average_length_of_episode)) %>%
ggplot(aes(x = quarter,
y = avg_length_of_episode)) +
geom_point() +
geom_line(aes(group = age,
colour = age))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

age_and_sex %>%
filter(!is.na(average_length_of_episode)) %>%
group_by(quarter, age) %>%
summarise(avg_length_of_episode = mean(average_length_of_episode)) %>%
ggplot(aes(x = quarter,
y = avg_length_of_episode)) +
geom_point() +
geom_line(aes(group = age,
colour = age))
age_and_sex %>%
filter(!is.na(average_length_of_episode)) %>%
group_by(quarter, sex) %>%
summarise(avg_length_of_episode = mean(average_length_of_episode)) %>%
ggplot(aes(x = quarter,
y = avg_length_of_episode)) +
geom_point() +
geom_line(aes(group = sex,
colour = sex))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

speciality %>%
filter(hb == "S92000003")
speciality %>%
group_by(quarter) %>%
summarise(mean_length_of_episode = mean(length_of_episode)) %>%
ggplot(aes(x = quarter,
y = mean_length_of_episode)) +
geom_point() +
geom_line(group = 1)
speciality %>%
group_by(quarter) %>%
summarise(mean_length_of_episode = mean(length_of_episode)) %>%
ggplot(aes(x = quarter,
y = mean_length_of_episode)) +
geom_point() +
geom_line(group = 1)
speciality %>%
group_by(quarter) %>%
summarise(mean_length_of_spell = mean(length_of_spell)) %>%
ggplot(aes(x = quarter,
y = mean_length_of_spell)) +
geom_point() +
geom_line(group = 1)
waiting_times <- read_csv("raw_data/non_covid_raw_data/monthly_ae_waitingtimes_202206.csv") %>% clean_names()
Rows: 15837 Columns: 25
── Column specification ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (13): Country, HBT, TreatmentLocation, DepartmentType, NumberOfAttendancesEpisodeQF, NumberMeetingTargetEpisodeQF, DischargeDestinationAdmissionToSameQF, DischargeDest...
dbl (12): Month, NumberOfAttendancesAggregate, NumberOfAttendancesEpisode, NumberMeetingTargetAggregate, NumberMeetingTargetEpisode, DischargeDestinationAdmissionToSame, D...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
waiting_times <- waiting_times %>%
mutate(date = ym(month),
quarter = quarter(date))
waiting_times %>%
mutate(pct = number_meeting_target_aggregate / number_of_attendances_aggregate * 100) %>%
group_by(date) %>%
summarise(mean_pct = mean(pct)) %>%
ggplot(aes(x = date,
y = mean_pct)) +
geom_line() +
geom_smooth()
waiting_times %>%
filter(department_type == "Emergency Department") %>%
mutate(pct = number_meeting_target_aggregate / number_of_attendances_aggregate * 100) %>%
group_by(date) %>%
summarise(mean_pct = mean(pct)) %>%
ggplot(aes(x = date,
y = mean_pct)) +
geom_line() +
geom_smooth()
waiting_times %>%
filter(department_type == "Minor Injury Unit or Other") %>%
mutate(pct = number_meeting_target_aggregate / number_of_attendances_aggregate * 100) %>%
group_by(date) %>%
summarise(mean_pct = mean(pct)) %>%
ggplot(aes(x = date,
y = mean_pct)) +
geom_line() +
geom_smooth()

library(fable)
Loading required package: fabletools
beds_fore <- beds_select %>%
mutate(quarter = yearquarter(date)) %>%
filter(!is.na(percentage_occupancy)) %>%
group_by(quarter) %>%
summarise(mean_pct = mean(percentage_occupancy))
beds_fore <- as_tsibble(beds_fore, index = quarter, validate = FALSE) %>%
select(quarter, mean_pct)
beds_fore <- beds_fore %>%
filter_index(~ "2019 Q4")
beds_fore %>%
autoplot(mean_pct)

fit <- beds_fore %>%
model(
snaive = SNAIVE(mean_pct),
mean_model = MEAN(mean_pct),
arima = ARIMA(mean_pct)
)
forecast_1 <- fit %>%
fabletools::forecast(h=12)
forecast_1
forecast_1 %>%
autoplot(beds_fore) +
guides(colour = guide_legend(title = "Forecast"))

wait_fore <- waiting_times %>%
mutate(month = ym(month),
month = yearmonth(month)) %>%
filter(!is.na(prop_residence)) %>%
group_by(month) %>%
summarise(mean_prop_residence = mean(prop_residence))
wait_fore <- as_tsibble(wait_fore, index = month, validate = FALSE)
wait_fore <- wait_fore %>%
filter_index(~ "2019-12-01")
wait_fore %>%
autoplot(mean_prop_residence)

fit_wait <- wait_fore %>%
model(
snaive = SNAIVE(mean_prop_residence),
mean_model = MEAN(mean_prop_residence),
arima = ARIMA(mean_prop_residence)
)
forecast_wait <- fit_wait %>%
fabletools::forecast(h=30)
forecast_wait
forecast_wait %>%
autoplot(wait_fore) +
guides(colour = guide_legend(title = "Forecast"))

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkoc2tpbXIpCmxpYnJhcnkodHNpYmJsZSkKbGlicmFyeShsdWJyaWRhdGUpCmBgYAoKCmBgYHtyfQpiZWRzIDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9ub25fY292aWRfcmF3X2RhdGEvYmVkc19ieV9uaHNfYm9hcmRfb2ZfdHJlYXRtZW50X2FuZF9zcGVjaWFsdHkuY3N2IikgJT4lIAogIGNsZWFuX25hbWVzKCkKYGBgCgoKYGBge3J9CmdsaW1wc2UoYmVkcykKYGBgCgoKYGBge3J9CnNraW0oYmVkcykKYGBgCgoKYGBge3J9CnZpZXcoYmVkcykKYGBgCgoKYGBge3J9CmJlZHMgJT4lIAogIGFycmFuZ2UoZGVzYyhhbGxfc3RhZmZlZF9iZWRkYXlzKSkKYGBgCgoKYGBge3J9CmJlZHMgJT4lIAogIGRpc3RpbmN0KGxvY2F0aW9uKQoKYmVkcyAlPiUgCiAgZGlzdGluY3QoaGIpCgpiZWRzICU+JSAKICBkaXN0aW5jdChhbGxfc3RhZmZlZF9iZWRkYXlzKQoKYmVkcyAlPiUgCiAgZGlzdGluY3QodG90YWxfb2NjdXBpZWRfYmVkZGF5cykKYGBgCgoKYGBge3J9CmJlZHMgJT4lIAogIGdncGxvdChhZXMoeCA9IGFsbF9zdGFmZmVkX2JlZGRheXMpKSArCiAgZ2VvbV9oaXN0b2dyYW0oY29sID0gIndoaXRlIikrCiAgc2NhbGVfeF9sb2cxMCgpCmBgYAoKCmBgYHtyfQpiZWRzICU+JSAKICBnZ3Bsb3QoYWVzKHggPSB0b3RhbF9vY2N1cGllZF9iZWRkYXlzKSkgKwogIGdlb21faGlzdG9ncmFtKGNvbCA9ICJ3aGl0ZSIpKwogIHNjYWxlX3hfbG9nMTAoKQpgYGAKCgpgYGB7cn0KYmVkcyAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gYXZlcmFnZV9vY2N1cGllZF9iZWRzKSkgKwogIGdlb21faGlzdG9ncmFtKGNvbCA9ICJ3aGl0ZSIpKwogIHNjYWxlX3hfbG9nMTAoKQpgYGAKCgpgYGB7cn0KYmVkcyAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcGVyY2VudGFnZV9vY2N1cGFuY3kpKSArCiAgZ2VvbV9oaXN0b2dyYW0oY29sID0gIndoaXRlIikKYGBgCgoKYGBge3J9CmJlZHNfc2VsZWN0IDwtIGJlZHMgJT4lIAogIG11dGF0ZShkYXRlID0geXEocXVhcnRlciksCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGUpLAogICAgICAgICBtb250aCA9IG1vbnRoKGRhdGUsIGxhYmVsID0gVFJVRSwgYWJiciA9IEZBTFNFKSwKICAgICAgICAgc2Vhc29uID0gY2FzZV93aGVuKAogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJKYW51YXJ5IikgfiAiV2ludGVyIiwKICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiQXByaWwiKSB+ICJTcHJpbmciLAogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJKdWx5IikgfiAiU3VtbWVyIiwKICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiT2N0b2JlciIpIH4gIkF1dHVtbiIpLAogICAgICAgICBzZWFzb24gPSBmYWN0b3Ioc2Vhc29uLCBvcmRlciA9IFRSVUUpKSAlPiUgCiAgc2VsZWN0KHF1YXJ0ZXIsIGhiLCBsb2NhdGlvbiwgc3BlY2lhbHR5X25hbWUsIGFsbF9zdGFmZmVkX2JlZGRheXMsIHRvdGFsX29jY3VwaWVkX2JlZGRheXMsIGF2ZXJhZ2VfYXZhaWxhYmxlX3N0YWZmZWRfYmVkcywgYXZlcmFnZV9vY2N1cGllZF9iZWRzLCBwZXJjZW50YWdlX29jY3VwYW5jeSwgZGF0ZSwgeWVhciwgbW9udGgsIHNlYXNvbikKYGBgCgoKYGBge3J9CmJlZHNfc2VsZWN0ICU+JSAKICBmaWx0ZXIoaGIgPT0gIlM5MjAwMDAwMyIpCmBgYAoKCmBgYHtyfQpiZWRzX3NlbGVjdCAlPiUKICBmaWx0ZXIoIWlzLm5hKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSwKICAgICAgICAgc3BlY2lhbHR5X25hbWUgPT0gIkFsbCBBY3V0ZSIpICU+JSAKICBncm91cF9ieShxdWFydGVyKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fcGVyY2VudGFnZV9vY2N1cGFuY3kgPSBtZWFuKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsCiAgICAgICAgICAgICB5ID0gbWVhbl9wZXJjZW50YWdlX29jY3VwYW5jeSkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShncm91cCA9IDEpCmBgYAoKCmBgYHtyfQpiZWRzX3NlbGVjdCAlPiUKICBmaWx0ZXIoIWlzLm5hKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkgJT4lIAogIGdyb3VwX2J5KHF1YXJ0ZXIpICU+JSAKICBzdW1tYXJpc2UobWVhbl9wZXJjZW50YWdlX29jY3VwYW5jeSA9IG1lYW4ocGVyY2VudGFnZV9vY2N1cGFuY3kpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwKICAgICAgICAgICAgIHkgPSBtZWFuX3BlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkgKwogIGdlb21fY29sKCkgCmBgYAoKCmBgYHtyfQpiZWRzX3NlbGVjdCAlPiUKICBmaWx0ZXIoIWlzLm5hKHRvdGFsX29jY3VwaWVkX2JlZGRheXMpKSAlPiUgCiAgZ3JvdXBfYnkocXVhcnRlcikgJT4lIAogIHN1bW1hcmlzZShtZWFuX29jY3VwaWVkX2JlZGRheXMgPSBtZWFuKHRvdGFsX29jY3VwaWVkX2JlZGRheXMpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwKICAgICAgICAgICAgIHkgPSBtZWFuX29jY3VwaWVkX2JlZGRheXMpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoZ3JvdXAgPSAxKQpgYGAKCgpgYGB7cn0KYmVkc19zZWxlY3QgJT4lCiAgZmlsdGVyKCFpcy5uYShhbGxfc3RhZmZlZF9iZWRkYXlzKSkgJT4lIAogIGdyb3VwX2J5KHF1YXJ0ZXIpICU+JSAKICBzdW1tYXJpc2UobWVhbl9zdGFmZmVkX2JlZGRheXMgPSBtZWFuKGFsbF9zdGFmZmVkX2JlZGRheXMpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwKICAgICAgICAgICAgIHkgPSBtZWFuX3N0YWZmZWRfYmVkZGF5cykpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShncm91cCA9IDEpCmBgYAoKCmBgYHtyfQpiZWRzX3NlbGVjdCAlPiUKICBmaWx0ZXIoIWlzLm5hKGF2ZXJhZ2VfYXZhaWxhYmxlX3N0YWZmZWRfYmVkcykpICU+JSAKICBncm91cF9ieShxdWFydGVyKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fYXZnX3N0YWZmZWRfYmVkZGF5cyA9IG1lYW4oYXZlcmFnZV9hdmFpbGFibGVfc3RhZmZlZF9iZWRzKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsCiAgICAgICAgICAgICB5ID0gbWVhbl9hdmdfc3RhZmZlZF9iZWRkYXlzKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGdyb3VwID0gMSkKYGBgCgoKYGBge3J9CmJlZHNfc2VsZWN0ICU+JQogIGZpbHRlcighaXMubmEoYXZlcmFnZV9hdmFpbGFibGVfc3RhZmZlZF9iZWRzKSkgJT4lIAogIG11dGF0ZShlbXB0eV9iZWRkYXlzID0gYWxsX3N0YWZmZWRfYmVkZGF5cyAtIHRvdGFsX29jY3VwaWVkX2JlZGRheXMpICU+JSAKICBncm91cF9ieShxdWFydGVyKSAlPiUKICBzdW1tYXJpc2UobWVhbl9lbXB0eSA9IG1lYW4oZW1wdHlfYmVkZGF5cykpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLAogICAgICAgICAgICAgeT0gbWVhbl9lbXB0eSkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShncm91cCA9IDEpCmBgYAoKCgpgYGB7cn0KYmVkc19zZWxlY3QgJT4lCiAgZmlsdGVyKCFpcy5uYShwZXJjZW50YWdlX29jY3VwYW5jeSkpICU+JSAKICBncm91cF9ieShxdWFydGVyLCBoYikgJT4lIAogIHN1bW1hcmlzZShtZWFuX3BlcmNlbnRhZ2Vfb2NjdXBhbmN5ID0gbWVhbihwZXJjZW50YWdlX29jY3VwYW5jeSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLAogICAgICAgICAgICAgeSA9IG1lYW5fcGVyY2VudGFnZV9vY2N1cGFuY3kpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gaGIsIGNvbG91ciA9IGhiKSkKYGBgCgoKYGBge3J9CmJlZHNfc2VsZWN0ICU+JQogIGZpbHRlcighaXMubmEocGVyY2VudGFnZV9vY2N1cGFuY3kpKSAlPiUgCiAgZ3JvdXBfYnkocXVhcnRlciwgc3BlY2lhbHR5X25hbWUsIGhiKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fcGVyY2VudGFnZV9vY2N1cGFuY3kgPSBtZWFuKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkgJT4lCiAgZmlsdGVyKG1lYW5fcGVyY2VudGFnZV9vY2N1cGFuY3kgPiA1MCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsCiAgICAgICAgICAgICB5ID0gbWVhbl9wZXJjZW50YWdlX29jY3VwYW5jeSkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzcGVjaWFsdHlfbmFtZSwgY29sb3VyID0gc3BlY2lhbHR5X25hbWUpKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgZmFjZXRfd3JhcCh+IGhiKQpgYGAKCgpgYGB7cn0KYmVkc19zZWxlY3QgJT4lIAogIGRpc3RpbmN0KHNwZWNpYWx0eV9uYW1lKQpgYGAKCgpgYGB7cn0KYmVkc19zZWxlY3QgJT4lIAogIGZpbHRlcihzcGVjaWFsdHlfbmFtZSAlaW4lIGMoIkFsbCBBY3V0ZSIsICJBY2NpZGVudCAmIEVtZXJnZW5jeSIsICJJbnRlbnNpdmUgQ2FyZSBNZWRpY2luZSIpKSAlPiUgCiAgZ3JvdXBfYnkocXVhcnRlciwgc3BlY2lhbHR5X25hbWUpICU+JSAKICBzdW1tYXJpc2UobWVhbl9wY3QgPSBtZWFuKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsCiAgICAgICAgICAgICB5ID0gbWVhbl9wY3QpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc3BlY2lhbHR5X25hbWUsIGNvbG91ciA9IHNwZWNpYWx0eV9uYW1lKSkKYGBgCgoKYGBge3J9CmJlZHNfc2VsZWN0ICU+JSAKICBmaWx0ZXIobG9jYXRpb24gPT0gIlMwODAwMDAxOSIsCiAgICAgICAgIHF1YXJ0ZXIgPT0gIjIwMTdRMSIpCmBgYAoKCmBgYHtyfQpiZWRzX3NlbGVjdCAlPiUKICBmaWx0ZXIoIWlzLm5hKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSwKICAgICAgICAgcGVyY2VudGFnZV9vY2N1cGFuY3kgPT0gMTAwKSAlPiUgCiAgZ3JvdXBfYnkocXVhcnRlciwgaGIpICU+JSAKICBzdW1tYXJpc2UobWVhbl9hdmdfb2NjdXBpZWRfYmVkcyA9IG1lYW4oYXZlcmFnZV9vY2N1cGllZF9iZWRzKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsCiAgICAgICAgICAgICB5ID0gbWVhbl9hdmdfb2NjdXBpZWRfYmVkcykpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBoYiwgY29sb3VyID0gaGIpKQpgYGAKCgpgCmBgYHtyfQpiZWRzX3NlbGVjdCAlPiUKICBmaWx0ZXIoIWlzLm5hKGF2ZXJhZ2Vfb2NjdXBpZWRfYmVkcykpICU+JSAKICBncm91cF9ieShxdWFydGVyKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fYXZlcmFnZV9vY2N1cGllZF9iZWRzID0gbWVhbihhdmVyYWdlX29jY3VwaWVkX2JlZHMpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwKICAgICAgICAgICAgIHkgPSBtZWFuX2F2ZXJhZ2Vfb2NjdXBpZWRfYmVkcykpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShncm91cCA9IDEpCmBgYAoKCgpgYGB7cn0KYmVkc19zZWxlY3QgJT4lIAogIGdyb3VwX2J5KHllYXIpICU+JSAKICBzdW1tYXJpc2UobWVhbl95ZWFyX2JlZCA9IG1lYW4oYXZlcmFnZV9vY2N1cGllZF9iZWRzKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHllYXIsCiAgICAgICAgICAgICB5ID0gbWVhbl95ZWFyX2JlZCkpICsKICBnZW9tX2xpbmUoKQpgYGAKCgpgYGB7cn0KYmVkc19zZWxlY3QgJT4lIAogIGdyb3VwX2J5KHNlYXNvbikgJT4lIAogIHN1bW1hcmlzZShtZWFuX3llYXJfYmVkID0gbWVhbihhdmVyYWdlX29jY3VwaWVkX2JlZHMpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc2Vhc29uLAogICAgICAgICAgICAgeSA9IG1lYW5feWVhcl9iZWQpKSArCiAgZ2VvbV9jb2woKSArIAogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiU3ByaW5nIiwgIlN1bW1lciIsICJBdXR1bW4iLCAiV2ludGVyIikpCmBgYAoKCgpgYGB7cn0KYmVkc19zZWxlY3QgJT4lIAogIGZpbHRlcighaXMubmEocGVyY2VudGFnZV9vY2N1cGFuY3kpKSAlPiUgCiAgZ3JvdXBfYnkoc2Vhc29uKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fcHJjdF9iZWRzID0gbWVhbihwZXJjZW50YWdlX29jY3VwYW5jeSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzZWFzb24sCiAgICAgICAgICAgICB5ID0gbWVhbl9wcmN0X2JlZHMpKSArCiAgZ2VvbV9jb2woKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJTcHJpbmciLCAiU3VtbWVyIiwgIkF1dHVtbiIsICJXaW50ZXIiKSkKYGBgCgoKYGBge3J9CmJlZHNfc2VsZWN0ICU+JSAKICBmaWx0ZXIoIWlzLm5hKHRvdGFsX29jY3VwaWVkX2JlZGRheXMpKSAlPiUgCiAgZ3JvdXBfYnkoc2Vhc29uKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fb2NjdXBpZWRfYmVkZGF5cyA9IG1lYW4odG90YWxfb2NjdXBpZWRfYmVkZGF5cykpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzZWFzb24sCiAgICAgICAgICAgICB5ID0gbWVhbl9vY2N1cGllZF9iZWRkYXlzKSkgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiU3ByaW5nIiwgIlN1bW1lciIsICJBdXR1bW4iLCAiV2ludGVyIikpCmBgYAoKCmBgYHtyfQpiZWRzX3NlbGVjdCAlPiUgCiAgZmlsdGVyKHF1YXJ0ZXIgPT0gIjIwMTZRNCIpCmBgYAoKCmBgYHtyfQpiZWRzX3NlbGVjdCAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc2Vhc29uLAogICAgICAgICAgICAgeSA9IHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkgKwogIGdlb21fY29sKCkgKwogIGZhY2V0X3dyYXAofiBzcGVjaWFsdHlfbmFtZSkKYGBgCgoKYGBge3J9CmJlZHNfc2VsZWN0ICU+JSAKICBmaWx0ZXIoIWlzLm5hKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkgJT4lIAogIGdyb3VwX2J5KHNwZWNpYWx0eV9uYW1lLCBtb250aCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3BjdF9zcGVjaWFsaXR5ID0gbWVhbihwZXJjZW50YWdlX29jY3VwYW5jeSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBtb250aCwKICAgICAgICAgICAgIHkgPSBtZWFuX3BjdF9zcGVjaWFsaXR5KSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHNwZWNpYWx0eV9uYW1lLCBjb2xvdXIgPSBzcGVjaWFsdHlfbmFtZSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgoKCmBgYHtyfQpiZWRzX3NlbGVjdCAlPiUKICBmaWx0ZXIocGVyY2VudGFnZV9vY2N1cGFuY3kgPT0gMTAwLAogICAgICAgICB5ZWFyID09IDIwMTcpICU+JSAKICBncm91cF9ieShzZWFzb24sIGhiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc2Vhc29uLAogICAgICAgICAgICAgeSA9IGNvdW50KSkgKwogIGdlb21fY29sKGFlcyhmaWxsID0gaGIpLCBwb3NpdGlvbiA9ICJkb2RnZSIpCgpgYGAKCgpgYGB7cn0KYmVkc19zZWxlY3QgJT4lIAogIG11dGF0ZShiaW5zID0gCiAgICBjYXNlX3doZW4ocGVyY2VudGFnZV9vY2N1cGFuY3kgPCAyNSB+ICI8MjUiLAogICAgICAgICAgICAgIHBlcmNlbnRhZ2Vfb2NjdXBhbmN5IDwgNTAgfiAiMjUtNTAiLAogICAgICAgICAgICAgIHBlcmNlbnRhZ2Vfb2NjdXBhbmN5IDwgNzUgfiAiNTAtNzUiLAogICAgICAgICAgICAgIHBlcmNlbnRhZ2Vfb2NjdXBhbmN5ID4gNzUgfiAiPjc1IgogICAgKQogICkgJT4lIAogIGZpbHRlcihiaW5zID09ICI8MjUiKSAlPiUgCiAgZ3JvdXBfYnkoc2Vhc29uKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKQpgYGAKCgoKYGBge3J9CmJlZHNfc2VsZWN0ICU+JSAKICBmaWx0ZXIoc3BlY2lhbHR5X25hbWUgPT0gIkFjY2lkZW50ICYgRW1lcmdlbmN5IikgJT4lCiAgZ3JvdXBfYnkocXVhcnRlcikgJT4lIAogIHN1bW1hcmlzZShtZWFuX3BjdCA9IG1lYW4ocGVyY2VudGFnZV9vY2N1cGFuY3kpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwKICAgICAgICAgICAgIHkgPSBtZWFuX3BjdCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShncm91cCA9IDEpCmBgYAoKCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKCgoKCmBgYHtyfQpzaW1kX3RyZWF0bWVudCA8LSByZWFkX2NzdigicmF3X2RhdGEvbm9uX2NvdmlkX3Jhd19kYXRhL2lucGF0aWVudF9hbmRfZGF5Y2FzZV9ieV9uaHNfYm9hcmRfb2ZfdHJlYXRtZW50X2FuZF9zaW1kLmNzdiIpICU+JSBjbGVhbl9uYW1lcygpCmBgYAoKCmBgYHtyfQpzaW1kX3RyZWF0bWVudCA8LSBzaW1kX3RyZWF0bWVudCAlPiUgCiAgbXV0YXRlKHNpbWQgPSBhcy5mYWN0b3Ioc2ltZCkpCmBgYAoKCmBgYHtyfQpzaW1kX3RyZWF0bWVudCAlPiUgCiAgZmlsdGVyKGhiID09ICJTOTIwMDAwMDMiKQpgYGAKCgpgYGB7cn0Kc2ltZF90cmVhdG1lbnQgJT4lIAogIGZpbHRlcighaXMubmEoYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSkpICU+JSAKICBncm91cF9ieShxdWFydGVyKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fYXZnX3N0YXkgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXkpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwKICAgICAgICAgICAgIHkgPSBtZWFuX2F2Z19zdGF5KSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGdyb3VwID0gMSkKYGBgCgoKYGBge3J9CnNpbWRfdHJlYXRtZW50ICU+JSAKICBmaWx0ZXIoIWlzLm5hKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXkpKSAlPiUgCiAgZ3JvdXBfYnkocXVhcnRlciwgYWRtaXNzaW9uX3R5cGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl9hdmdfc3RheSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLAogICAgICAgICAgICAgeSA9IG1lYW5fYXZnX3N0YXkpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gYWRtaXNzaW9uX3R5cGUsIGNvbG91ciA9IGFkbWlzc2lvbl90eXBlKSkKYGBgCgoKYGBge3J9CnNpbWRfdHJlYXRtZW50ICU+JSAKICBmaWx0ZXIoIWlzLm5hKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXkpKSAlPiUgCiAgZ3JvdXBfYnkocXVhcnRlciwgc2ltZCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX2F2Z19zdGF5ID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9zdGF5KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsCiAgICAgICAgICAgICB5ID0gbWVhbl9hdmdfc3RheSkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzaW1kLCBjb2xvdXIgPSBzaW1kKSkKYGBgCgoKYGBge3J9CnNpbWRfdHJlYXRtZW50ICU+JSAKICBmaWx0ZXIoIWlzLm5hKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXkpLAogICAgICAgICBzaW1kID09IDUpICU+JSAKICBncm91cF9ieShxdWFydGVyLCBzaW1kKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fYXZnX3N0YXkgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXkpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwKICAgICAgICAgICAgIHkgPSBtZWFuX2F2Z19zdGF5KSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHNpbWQsIGNvbG91ciA9IHNpbWQpKQpgYGAKCgpgYGB7cn0Kc2ltZF90cmVhdG1lbnQgJT4lIAogIGZpbHRlcighaXMubmEoYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSksCiAgICAgICAgIHNpbWQgPT0gMSkgJT4lIAogIG11dGF0ZShzaW1kID0gcmVwbGFjZV9uYShzaW1kLCAwKSkgJT4lIAogIGdyb3VwX2J5KHF1YXJ0ZXIsIHNpbWQpICU+JSAKICBzdW1tYXJpc2UobWVhbl9hdmdfc3RheSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLAogICAgICAgICAgICAgeSA9IG1lYW5fYXZnX3N0YXkpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc2ltZCwgY29sb3VyID0gc2ltZCkpCmBgYAoKCgpgYGB7cn0Kc2ltZF90cmVhdG1lbnQgJT4lIAogIGZpbHRlcighaXMubmEoYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSkpICU+JSAKICBncm91cF9ieShxdWFydGVyLCBzaW1kKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fYXZnX3N0YXkgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXkpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwKICAgICAgICAgICAgIHkgPSBtZWFuX2F2Z19zdGF5KSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHNpbWQsIGNvbG91ciA9IHNpbWQpKQpgYGAKCgoKYGBge3J9CnNpbWRfdHJlYXRtZW50ICU+JSAKICBmaWx0ZXIoIWlzLm5hKGF2ZXJhZ2VfbGVuZ3RoX29mX2VwaXNvZGUpKSAlPiUgCiAgZ3JvdXBfYnkocXVhcnRlcikgJT4lIAogIHN1bW1hcmlzZShtZWFuX2F2Z19lcGlzb2RlID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9lcGlzb2RlKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsCiAgICAgICAgICAgICB5ID0gbWVhbl9hdmdfZXBpc29kZSkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShncm91cCA9IDEpCmBgYAoKCmBgYHtyfQpzaW1kX3RyZWF0bWVudCAlPiUgCiAgZmlsdGVyKCFpcy5uYShhdmVyYWdlX2xlbmd0aF9vZl9lcGlzb2RlKSkgJT4lIAogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFkbWlzc2lvbl90eXBlKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fYXZnX2VwaWRzb2RlID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9lcGlzb2RlKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsCiAgICAgICAgICAgICB5ID0gbWVhbl9hdmdfZXBpZHNvZGUpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gYWRtaXNzaW9uX3R5cGUsIGNvbG91ciA9IGFkbWlzc2lvbl90eXBlKSkKYGBgCgoKYGBge3J9CnNpbWRfdHJlYXRtZW50ICU+JSAKICBmaWx0ZXIoIWlzLm5hKGF2ZXJhZ2VfbGVuZ3RoX29mX2VwaXNvZGUpKSAlPiUgCiAgZ3JvdXBfYnkocXVhcnRlciwgc2ltZCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX2F2Z19lcGlkc29kZSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2ZfZXBpc29kZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLAogICAgICAgICAgICAgeSA9IG1lYW5fYXZnX2VwaWRzb2RlKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHNpbWQsIGNvbG91ciA9IHNpbWQpKQpgYGAKCgpgYGB7cn0Kc2ltZF90cmVhdG1lbnQgJT4lIAogIGZpbHRlcighaXMubmEoYXZlcmFnZV9sZW5ndGhfb2ZfZXBpc29kZSksCiAgICAgICAgIHNpbWQgPT0gNSkgJT4lIAogIGdyb3VwX2J5KHF1YXJ0ZXIpICU+JSAKICBzdW1tYXJpc2UobWVhbl9hdmdfZXBpc29kZSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2ZfZXBpc29kZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLAogICAgICAgICAgICAgeSA9IG1lYW5fYXZnX2VwaXNvZGUpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoZ3JvdXAgPSAxKQpgYGAKCgpgYGB7cn0Kc2ltZF90cmVhdG1lbnQgJT4lIAogIGZpbHRlcighaXMubmEoYXZlcmFnZV9sZW5ndGhfb2ZfZXBpc29kZSksCiAgICAgICAgIHNpbWQgPT0gMSkgJT4lIAogIGdyb3VwX2J5KHF1YXJ0ZXIpICU+JSAKICBzdW1tYXJpc2UobWVhbl9hdmdfZXBpc29kZSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2ZfZXBpc29kZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLAogICAgICAgICAgICAgeSA9IG1lYW5fYXZnX2VwaXNvZGUpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoZ3JvdXAgPSAxKQpgYGAKCgpgYGB7cn0Kc2ltZF90cmVhdG1lbnQgJT4lIAogIGZpbHRlcighaXMubmEoZXBpc29kZXMpKSAlPiUgCiAgZ3JvdXBfYnkocXVhcnRlciwgc2ltZCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX2VwaWRzb2RlID0gbWVhbihlcGlzb2RlcykpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLAogICAgICAgICAgICAgeSA9IG1lYW5fZXBpZHNvZGUpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc2ltZCwgY29sb3VyID0gc2ltZCkpCmBgYAoKCmBgYHtyfQpzaW1kX3RyZWF0bWVudCAlPiUgCiAgZmlsdGVyKGlzLm5hKHNpbWQpKQpgYGAKCgpgYGB7cn0Kc2ltZF90cmVhdG1lbnQgJT4lIAogIGZpbHRlcighaXMubmEoc3RheXMpKSAlPiUgCiAgZ3JvdXBfYnkocXVhcnRlciwgc2ltZCkgJT4lIAogIHN1bW1hcmlzZSh0b3RhbF9zdGF5cyA9IHN1bShzdGF5cykpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLAogICAgICAgICAgICAgeSA9IHRvdGFsX3N0YXlzKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHNpbWQsIGNvbG91ciA9IHNpbWQpKQpgYGAKCgoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCgpgYGB7cn0KYWdlX2FuZF9zZXggPC0gcmVhZF9jc3YoInJhd19kYXRhL25vbl9jb3ZpZF9yYXdfZGF0YS9pbnBhdGllbnRfYW5kX2RheWNhc2VfYnlfbmhzX2JvYXJkX29mX3RyZWF0bWVudF9hZ2VfYW5kX3NleC5jc3YiKSAlPiUgIGNsZWFuX25hbWVzKCkKYGBgCgoKYGBge3J9CmFnZV9hbmRfc2V4IDwtIGFnZV9hbmRfc2V4ICU+JSAKICBtdXRhdGUoc2V4ID0gYXMuZmFjdG9yKHNleCkpCmBgYAoKCmBgYHtyfQphZ2VfYW5kX3NleCAlPiUgCiAgZmlsdGVyKHNleCA9PSAiRmVtYWxlIiwKICAgICAgICAgYWdlID09ICIwLTkgeWVhcnMiKQpgYGAKCgpgYGB7cn0KYWdlX2FuZF9zZXggJT4lCiAgZmlsdGVyKCFpcy5uYShhdmVyYWdlX2xlbmd0aF9vZl9zdGF5KSkgJT4lIAogIGdyb3VwX2J5KHF1YXJ0ZXIpICU+JSAKICBzdW1tYXJpc2UoYXZnX2xlbmd0aF9vZl9zdGF5ID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9zdGF5KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsCiAgICAgICAgICAgICB5ID0gYXZnX2xlbmd0aF9vZl9zdGF5KSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGdyb3VwID0gMSkKYGBgCgoKYGBge3J9CmFnZV9hbmRfc2V4ICU+JSAKICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSAKICBzdW1tYXJpc2UobGVuZ3RoX29mX3N0YXkgPSBtZWFuKGxlbmd0aF9vZl9zdGF5KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsCiAgICAgICAgICAgICB5ID0gbGVuZ3RoX29mX3N0YXkpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gYWdlLAogICAgICAgICAgICAgICAgY29sb3VyID0gYWdlKSkKYGBgCgoKYGBge3J9CmFnZV9hbmRfc2V4ICU+JQogIGZpbHRlcighaXMubmEoYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSkpICU+JSAKICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSAKICBzdW1tYXJpc2UoYXZnX2xlbmd0aF9vZl9zdGF5ID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9zdGF5KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsCiAgICAgICAgICAgICB5ID0gYXZnX2xlbmd0aF9vZl9zdGF5KSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGFnZSwKICAgICAgICAgICAgICAgIGNvbG91ciA9IGFnZSkpCmBgYAoKCmBgYHtyfQphZ2VfYW5kX3NleCAlPiUKICBmaWx0ZXIoIWlzLm5hKGF2ZXJhZ2VfbGVuZ3RoX29mX2VwaXNvZGUpLAogICAgICAgICBhZ2UgPT0gIjEwLTE5IHllYXJzIiwKICAgICAgICAgc2V4ID09ICJGZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkocXVhcnRlciwgYWdlKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19sZW5ndGhfb2ZfZXBpc29kZSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2ZfZXBpc29kZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLAogICAgICAgICAgICAgeSA9IGF2Z19sZW5ndGhfb2ZfZXBpc29kZSkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBhZ2UsCiAgICAgICAgICAgICAgICBjb2xvdXIgPSBhZ2UpKQpgYGAKCgpgYGB7cn0KYWdlX2FuZF9zZXggJT4lCiAgZmlsdGVyKCFpcy5uYShhdmVyYWdlX2xlbmd0aF9vZl9lcGlzb2RlKSkgJT4lIAogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFnZSkgJT4lIAogIHN1bW1hcmlzZShhdmdfbGVuZ3RoX29mX2VwaXNvZGUgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX2VwaXNvZGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwKICAgICAgICAgICAgIHkgPSBhdmdfbGVuZ3RoX29mX2VwaXNvZGUpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gYWdlLAogICAgICAgICAgICAgICAgY29sb3VyID0gYWdlKSkKYGBgCgoKCmBgYHtyfQphZ2VfYW5kX3NleCAlPiUKICBmaWx0ZXIoIWlzLm5hKGF2ZXJhZ2VfbGVuZ3RoX29mX2VwaXNvZGUpKSAlPiUgCiAgZ3JvdXBfYnkocXVhcnRlciwgc2V4KSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19sZW5ndGhfb2ZfZXBpc29kZSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2ZfZXBpc29kZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLAogICAgICAgICAgICAgeSA9IGF2Z19sZW5ndGhfb2ZfZXBpc29kZSkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzZXgsCiAgICAgICAgICAgICAgICBjb2xvdXIgPSBzZXgpKQpgYGAKCgoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCgoKYGBge3J9CnNwZWNpYWxpdHkgPC0gcmVhZF9jc3YoInJhd19kYXRhL25vbl9jb3ZpZF9yYXdfZGF0YS9pbnBhdGllbnRfYW5kX2RheWNhc2VfYnlfbmhzX2JvYXJkX29mX3RyZWF0bWVudF9hbmRfc3BlY2lhbHR5LmNzdiIpICU+JSBjbGVhbl9uYW1lcygpCmBgYAoKCmBgYHtyfQpzcGVjaWFsaXR5ICU+JSAKICBmaWx0ZXIoaGIgPT0gIlM5MjAwMDAwMyIpCmBgYAoKCmBgYHtyfQpzcGVjaWFsaXR5ICU+JSAKICBncm91cF9ieShxdWFydGVyKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fbGVuZ3RoX29mX2VwaXNvZGUgPSBtZWFuKGxlbmd0aF9vZl9lcGlzb2RlKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsCiAgICAgICAgICAgICB5ID0gbWVhbl9sZW5ndGhfb2ZfZXBpc29kZSkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShncm91cCA9IDEpIApgYGAKCgpgYGB7cn0Kc3BlY2lhbGl0eSAlPiUgCiAgZ3JvdXBfYnkocXVhcnRlcikgJT4lIAogIHN1bW1hcmlzZShtZWFuX2xlbmd0aF9vZl9lcGlzb2RlID0gbWVhbihsZW5ndGhfb2ZfZXBpc29kZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLAogICAgICAgICAgICAgeSA9IG1lYW5fbGVuZ3RoX29mX2VwaXNvZGUpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoZ3JvdXAgPSAxKSAKYGBgCgoKYGBge3J9CnNwZWNpYWxpdHkgJT4lIAogIGdyb3VwX2J5KHF1YXJ0ZXIpICU+JSAKICBzdW1tYXJpc2UobWVhbl9sZW5ndGhfb2Zfc3BlbGwgPSBtZWFuKGxlbmd0aF9vZl9zcGVsbCkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLAogICAgICAgICAgICAgeSA9IG1lYW5fbGVuZ3RoX29mX3NwZWxsKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGdyb3VwID0gMSkKYGBgCgoKCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKCmBgYHtyfQp3YWl0aW5nX3RpbWVzIDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9ub25fY292aWRfcmF3X2RhdGEvbW9udGhseV9hZV93YWl0aW5ndGltZXNfMjAyMjA2LmNzdiIpICU+JSBjbGVhbl9uYW1lcygpCmBgYAoKCmBgYHtyfQp3YWl0aW5nX3RpbWVzIDwtIHdhaXRpbmdfdGltZXMgJT4lIAogIG11dGF0ZShkYXRlID0geW0obW9udGgpLAogICAgICAgICBxdWFydGVyID0gcXVhcnRlcihkYXRlKSkKYGBgCgoKYGBge3J9CndhaXRpbmdfdGltZXMgJT4lIAogIG11dGF0ZShwY3QgPSBudW1iZXJfbWVldGluZ190YXJnZXRfYWdncmVnYXRlIC8gbnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSAqIDEwMCkgJT4lCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3BjdCA9IG1lYW4ocGN0KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGRhdGUsCiAgICAgICAgICAgICB5ID0gbWVhbl9wY3QpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fc21vb3RoKCkKYGBgCgoKYGBge3J9CndhaXRpbmdfdGltZXMgJT4lIAogIGZpbHRlcihkZXBhcnRtZW50X3R5cGUgPT0gIkVtZXJnZW5jeSBEZXBhcnRtZW50IikgJT4lIAogIG11dGF0ZShwY3QgPSBudW1iZXJfbWVldGluZ190YXJnZXRfYWdncmVnYXRlIC8gbnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSAqIDEwMCkgJT4lCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3BjdCA9IG1lYW4ocGN0KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGRhdGUsCiAgICAgICAgICAgICB5ID0gbWVhbl9wY3QpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fc21vb3RoKCkKYGBgCgoKYGBge3J9CndhaXRpbmdfdGltZXMgJT4lIAogIGZpbHRlcihkZXBhcnRtZW50X3R5cGUgPT0gIk1pbm9yIEluanVyeSBVbml0IG9yIE90aGVyIikgJT4lIAogIG11dGF0ZShwY3QgPSBudW1iZXJfbWVldGluZ190YXJnZXRfYWdncmVnYXRlIC8gbnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSAqIDEwMCkgJT4lCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3BjdCA9IG1lYW4ocGN0KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGRhdGUsCiAgICAgICAgICAgICB5ID0gbWVhbl9wY3QpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fc21vb3RoKCkKYGBgCgoKCmBgYHtyfQp3YWl0aW5nX3RpbWVzIDwtIHdhaXRpbmdfdGltZXMgJT4lIAogIG11dGF0ZSgKICAgIHByb3BfYWRtaXNzaW9uX3RvX3NhbWUgPSAoZGlzY2hhcmdlX2Rlc3RpbmF0aW9uX2FkbWlzc2lvbl90b19zYW1lL251bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUpCiAgKSAlPiUgCiAgbXV0YXRlKHByb3Bfb3RoZXJfc3BlY2lhbGl0eSA9IChkaXNjaGFyZ2VfZGVzdGluYXRpb25fb3RoZXJfc3BlY2lhbHR5L251bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUpKSAlPiUgCiAgbXV0YXRlKHByb3BfcmVzaWRlbmNlID0gKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl9yZXNpZGVuY2UvbnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSkpICU+JSAKICBtdXRhdGUocHJvcF90cmFuc2ZlciA9IChkaXNjaGFyZ2VfZGVzdGluYXRpb25fdHJhbnNmZXIvbnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSkpICU+JSAKICBtdXRhdGUocHJvcF91bmtub3duID0gKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl91bmtub3duL251bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUpKSAKYGBgCgpgYGB7cn0Kd2FpdGluZ190aW1lcyAlPiUgCiAgZmlsdGVyKCFpcy5uYShwcm9wX2FkbWlzc2lvbl90b19zYW1lKSkgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl9hZG1pc3Npb25fdG9fc2FtZSA9IG1lYW4ocHJvcF9hZG1pc3Npb25fdG9fc2FtZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBkYXRlLAogICAgICAgICB5ID0gbWVhbl9hZG1pc3Npb25fdG9fc2FtZSkpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjYgbW9udGhzIiwgZGF0ZV9sYWJlbHMgPSAgIiViICVZIikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAwOC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDA5LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTAtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEyLTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTMtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE1LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTYtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNy0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE4LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTktMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAyMC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIxLTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjItMDEtMDEiKSksIGxpbmV0eXBlPTQpCgp3YWl0aW5nX3RpbWVzICU+JSAKICBmaWx0ZXIoIWlzLm5hKHByb3Bfb3RoZXJfc3BlY2lhbGl0eSkpICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fb3RoZXJfc3BlY2lhbGl0eSA9IG1lYW4ocHJvcF9vdGhlcl9zcGVjaWFsaXR5KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGRhdGUsCiAgICAgICAgIHkgPSBtZWFuX290aGVyX3NwZWNpYWxpdHkpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAwOC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDA5LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTAtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEyLTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTMtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE1LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTYtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNy0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE4LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTktMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAyMC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIxLTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjItMDEtMDEiKSksIGxpbmV0eXBlPTQpCgp3YWl0aW5nX3RpbWVzICU+JSAKICBmaWx0ZXIoIWlzLm5hKHByb3BfcmVzaWRlbmNlKSkgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl9yZXNpZGVuY2UgPSBtZWFuKHByb3BfcmVzaWRlbmNlKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGRhdGUsCiAgICAgICAgIHkgPSBtZWFuX3Jlc2lkZW5jZSkpICsKICBnZW9tX2xpbmUoKSsKICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiNiBtb250aHMiLCBkYXRlX2xhYmVscyA9ICAiJWIgJVkiKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDA4LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMDktMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDExLTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTItMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMy0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE0LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTUtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNi0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE3LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTgtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxOS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIwLTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjEtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAyMi0wMS0wMSIpKSwgbGluZXR5cGU9NCkKCndhaXRpbmdfdGltZXMgJT4lIAogIGZpbHRlcighaXMubmEocHJvcF90cmFuc2ZlcikpICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fdHJhbnNmZXIgPSBtZWFuKHByb3BfdHJhbnNmZXIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZSwKICAgICAgICAgeSA9IG1lYW5fdHJhbnNmZXIpKSArCiAgZ2VvbV9saW5lKCkgKwogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICI2IG1vbnRocyIsIGRhdGVfbGFiZWxzID0gICIlYiAlWSIpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMDgtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAwOS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEwLTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTEtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMi0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEzLTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTQtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE2LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTctMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxOC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE5LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjAtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAyMS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIyLTAxLTAxIikpLCBsaW5ldHlwZT00KQoKd2FpdGluZ190aW1lcyAlPiUgCiAgZmlsdGVyKCFpcy5uYShwcm9wX3Vua25vd24pKSAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3Vua25vd24gPSBtZWFuKHByb3BfdW5rbm93bikpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBkYXRlLAogICAgICAgICB5ID0gbWVhbl91bmtub3duKSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiNiBtb250aHMiLCBkYXRlX2xhYmVscyA9ICAiJWIgJVkiKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDA4LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMDktMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDExLTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTItMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMy0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE0LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTUtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNi0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE3LTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTgtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxOS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIwLTAxLTAxIikpLCBsaW5ldHlwZT00KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjEtMDEtMDEiKSksIGxpbmV0eXBlPTQpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAyMi0wMS0wMSIpKSwgbGluZXR5cGU9NCkKYGBgCgoKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgoKCmBgYHtyfQpsaWJyYXJ5KGZhYmxlKQpgYGAKCgpgYGB7cn0KYmVkc19mb3JlIDwtIGJlZHNfc2VsZWN0ICU+JQogIG11dGF0ZShxdWFydGVyID0geWVhcnF1YXJ0ZXIoZGF0ZSkpICU+JSAKICBmaWx0ZXIoIWlzLm5hKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkgJT4lIAogIGdyb3VwX2J5KHF1YXJ0ZXIpICU+JSAKICBzdW1tYXJpc2UobWVhbl9wY3QgPSBtZWFuKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkKCgpiZWRzX2ZvcmUgPC0gYXNfdHNpYmJsZShiZWRzX2ZvcmUsIGluZGV4ID0gcXVhcnRlciwgdmFsaWRhdGUgPSBGQUxTRSkgJT4lIAogIHNlbGVjdChxdWFydGVyLCBtZWFuX3BjdCkKCmJlZHNfZm9yZSA8LSBiZWRzX2ZvcmUgJT4lIAogIGZpbHRlcl9pbmRleCh+ICIyMDE5IFE0IikKCmJlZHNfZm9yZSAlPiUgCiAgYXV0b3Bsb3QobWVhbl9wY3QpCmBgYAoKCmBgYHtyfQpmaXQgPC0gYmVkc19mb3JlICU+JSAKICBtb2RlbCgKICAgIHNuYWl2ZSA9IFNOQUlWRShtZWFuX3BjdCksCiAgICBtZWFuX21vZGVsID0gTUVBTihtZWFuX3BjdCksCiAgICBhcmltYSA9IEFSSU1BKG1lYW5fcGN0KQogICkKYGBgCgoKYGBge3J9CmZvcmVjYXN0XzEgPC0gZml0ICU+JSAKICBmYWJsZXRvb2xzOjpmb3JlY2FzdChoPTEyKQoKZm9yZWNhc3RfMQpgYGAKCgpgYGB7cn0KZm9yZWNhc3RfMSAlPiUgCiAgYXV0b3Bsb3QoYmVkc19mb3JlKSArCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJGb3JlY2FzdCIpKQpgYGAKCgoKCmBgYHtyfQp3YWl0X2ZvcmUgPC0gd2FpdGluZ190aW1lcyAlPiUgCiAgbXV0YXRlKG1vbnRoID0geW0obW9udGgpLAogICAgICAgICBtb250aCA9IHllYXJtb250aChtb250aCkpICU+JSAKICBmaWx0ZXIoIWlzLm5hKHByb3BfcmVzaWRlbmNlKSkgJT4lIAogIGdyb3VwX2J5KG1vbnRoKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fcHJvcF9yZXNpZGVuY2UgPSBtZWFuKHByb3BfcmVzaWRlbmNlKSkKCndhaXRfZm9yZSA8LSBhc190c2liYmxlKHdhaXRfZm9yZSwgaW5kZXggPSBtb250aCwgdmFsaWRhdGUgPSBGQUxTRSkKCndhaXRfZm9yZSA8LSB3YWl0X2ZvcmUgJT4lIAogIGZpbHRlcl9pbmRleCh+ICIyMDE5LTEyLTAxIikKCndhaXRfZm9yZSAlPiUgCiAgYXV0b3Bsb3QobWVhbl9wcm9wX3Jlc2lkZW5jZSkKYGBgCgoKYGBge3J9CmZpdF93YWl0IDwtIHdhaXRfZm9yZSAlPiUgCiAgbW9kZWwoCiAgICBzbmFpdmUgPSBTTkFJVkUobWVhbl9wcm9wX3Jlc2lkZW5jZSksCiAgICBtZWFuX21vZGVsID0gTUVBTihtZWFuX3Byb3BfcmVzaWRlbmNlKSwKICAgIGFyaW1hID0gQVJJTUEobWVhbl9wcm9wX3Jlc2lkZW5jZSkKICApCmBgYAoKCmBgYHtyfQpmb3JlY2FzdF93YWl0IDwtIGZpdF93YWl0ICU+JSAKICBmYWJsZXRvb2xzOjpmb3JlY2FzdChoPTMwKQoKZm9yZWNhc3Rfd2FpdApgYGAKCgoKYGBge3J9CmZvcmVjYXN0X3dhaXQgJT4lIAogIGF1dG9wbG90KHdhaXRfZm9yZSkgKwogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiRm9yZWNhc3QiKSkKYGBgCgoKCgoK